<template>
	<div
		v-if="props.tableSearch.filter(v => !v.isHide).length > 0"
		class="table-control-search-container"
		:style="{ height: state.isShowSearch ? state.rowHeight + 'px' : '0' }"
	>
		<el-form
			ref="formRef"
			class="table-form"
			:model="state.ruleForm"
			:size="themeConfig.globalComponentSize"
			label-width="auto"
		>
			<el-row id="table-control-search-row" :gutter="12">
				<template v-for="val in props.tableSearch">
					<el-col
						v-if="!val.isHide"
						:key="val.prop"
						:xs="24"
						:sm="12"
						:md="val.type.includes('multi') || val.type.includes('Range') ? 12 : 8"
						:lg="val.type.includes('multi') || val.type.includes('Range') ? 8 : 6"
						:xl="val.type.includes('multi') || val.type.includes('Range') ? 6 : 4"
						class="mb10"
					>
						<el-form-item
							:label="val.label"
							:prop="val.prop"
							:rules="[
								{
									required: val.required,
									message: `${val.label}不能为空`,
									trigger: val.type === 'input' ? 'blur' : 'change',
								},
							]"
						>
							<el-input
								v-if="val.type === 'input'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								clearable
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-input-number
								v-else-if="val.type === 'number'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:min="val.min"
								:max="val.max"
								:step="val.step"
								:precision="val.precision"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-select
								v-else-if="val.type === 'select'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:multiple="val.multiple"
								clearable
								filterable
								style="width: 100%"
								@change="val.onChange"
							>
								<el-option
									v-for="item in val.options"
									:key="item.value"
									:label="item.label"
									:value="item.value"
								>
								</el-option>
							</el-select>
							<el-tree-select
								v-else-if="val.type === 'treeSelect'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:data="val.options || []"
								:props="
									val.treeProps || {
										label: 'label',
										value: 'id',
										children: 'children',
										disabled: 'disabled',
									}
								"
								:check-strictly="val.isCheckStrictly"
								:filter-node-method="(value: string, data: EmptyObjectType) => filterTreeNode(value, data, val.treeProps)"
								:multiple="val.multiple"
								filterable
								clearable
								node-key="id"
								style="width: 100%"
								@node-click="val.onNodeClick"
							/>
							<el-date-picker
								v-else-if="val.type === 'date'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:value-format="val.valueFormat"
								type="date"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-time-picker
								v-else-if="val.type === 'time'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:value-format="val.valueFormat"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-date-picker
								v-else-if="val.type === 'datetime'"
								v-model="state.ruleForm[val.prop]"
								:placeholder="val.placeholder"
								:value-format="val.valueFormat"
								type="datetime"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-date-picker
								v-else-if="val.type === 'dateRange'"
								v-model="state.ruleForm[val.prop]"
								:value-format="val.valueFormat"
								start-placeholder="开始日期"
								end-placeholder="结束日期"
								type="daterange"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-time-picker
								v-else-if="val.type === 'timeRange'"
								v-model="state.ruleForm[val.prop]"
								:value-format="val.valueFormat"
								start-placeholder="开始时间"
								end-placeholder="结束时间"
								is-range
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-date-picker
								v-else-if="val.type === 'datetimeRange'"
								v-model="state.ruleForm[val.prop]"
								:default-time="[new Date(2025, 12, 12, 0, 0, 0), new Date(2025, 12, 12, 23, 59, 59)]"
								:value-format="val.valueFormat"
								start-placeholder="开始时间"
								end-placeholder="结束时间"
								type="datetimerange"
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-cascader
								v-else-if="val.type === 'cascader'"
								v-model="state.ruleForm[val.prop]"
								:options="val.options || []"
								:props="{
									expandTrigger: 'hover',
									value: 'value',
									label: 'label',
									children: 'children',
								}"
								:placeholder="val.placeholder"
								filterable
								clearable
								style="width: 100%"
								@change="val.onChange"
							/>
							<el-rate
								v-else-if="val.type === 'rate'"
								v-model="state.ruleForm[val.prop]"
								:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
								size="default"
								clearable
								allow-half
								show-score
								score-template="{value} 星"
								style="width: 100%"
								@change="val.onChange"
							/>
							<template v-else-if="val.type === 'slot'">
								<slot :name="val.prop" :ruleForm="state.ruleForm"></slot>
							</template>
						</el-form-item>
					</el-col>
				</template>
				<el-col :xs="12" :sm="6" :md="6" :lg="4" :xl="4" class="mb10">
					<div class="">
						<el-button type="primary" @click="onSearch">查询</el-button>
						<el-button type="info" @click="onReset">重置</el-button>
					</div>
				</el-col>
			</el-row>
		</el-form>
	</div>
	<div class="table-control-container mb10">
		<!-- 左侧 -->
		<div class="operation-box">
			<el-tooltip placement="top" content="刷新表格">
				<el-button color="#409eff" :size="themeConfig.globalComponentSize" @click="$emit('refresh')">
					<HIcon name="fa fa-refresh" class="icon-btn" color="#fff" :size="16" />
				</el-button>
			</el-tooltip>
			<slot name="operationBtn"></slot>
		</div>
		<!-- 右侧 -->
		<div class="tool-box">
			<div class="tool-input-group mr15">
				<slot name="quickSearch"></slot>
			</div>
			<div class="tool-btn-group">
				<el-tooltip placement="top" :content="state.isShowSearch ? '关闭搜索' : '展开搜索'">
					<el-button
						class="tool-btn border-right"
						plain
						:size="themeConfig.globalComponentSize"
						@click="onShowSearch"
					>
						<HIcon class="icon-btn" name="fa fa-search" color="#606266" :size="16" />
					</el-button>
				</el-tooltip>
				<!-- <el-tooltip placement="top" content="导出表格">
					<el-button
						class="tool-btn border-right"
						plain
						:size="themeConfig.globalComponentSize"
						@click="onExportTable"
					>
						<HIcon class="icon-btn" name="fa fa-cloud-download" color="#606266" :size="16" />
					</el-button>
				</el-tooltip> -->
				<el-tooltip placement="top" content="表格设置">
					<el-button ref="settingIconRef" class="tool-btn" plain :size="themeConfig.globalComponentSize">
						<HIcon class="icon-btn" name="fa fa-th" color="#606266" :size="16" />
					</el-button>
				</el-tooltip>
				<el-popover
					ref="settingRef"
					:virtual-ref="settingIconRef"
					virtual-triggering
					trigger="click"
					placement="bottom-end"
					transition="el-zoom-in-top"
					popper-class="table-tool-popper"
					width="300"
					persistent
					@show="onSetTable"
				>
					<template #default>
						<div class="tool-box">
							<el-tooltip content="拖动下方的箭头图标进行排序" placement="top-start">
								<HIcon name="fa fa-question-circle-o" :size="17" class="ml11" color="#909399" />
							</el-tooltip>
							<el-checkbox
								v-model="state.checkListAll"
								:indeterminate="state.checkListIndeterminate"
								class="ml10 mr1"
								label="列显示"
								@change="onCheckAllChange"
							/>
							<el-checkbox v-model="config.isSerialNo" class="ml12 mr1" label="序号" />
							<el-checkbox v-model="config.isSelection" class="ml12 mr1" label="多选" />
							<el-checkbox v-model="config.isBorder" class="ml12 mr1" label="边框" />
						</div>
						<el-scrollbar>
							<div ref="toolSetRef" class="tool-sortable">
								<div class="tool-sortable-item" v-for="v in props.header" :key="v.key" :data-key="v.key">
									<i class="fa fa-arrows-alt handle cursor-grab"></i>
									<el-checkbox
										v-model="v.isCheck"
										size="default"
										class="ml12 mr8"
										:label="v.title"
										@change="onCheckChange"
									/>
								</div>
							</div>
						</el-scrollbar>
					</template>
				</el-popover>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts" name="tableControl">
import { reactive, ref, watch, nextTick, onMounted } from "vue";
import type { FormInstance } from "element-plus";
// import { ElMessage } from "element-plus";
import { storeToRefs } from "pinia";
import { useThemeConfig } from "/@/stores/themeConfig";
import { cloneDeep } from "lodash-es";
// import table2excel from "js-table2excel";
import Sortable from "sortablejs";
import "/@/theme/tableTool.scss";

// 定义传值
interface TableControlProps {
	config: TableConfigType; // 表格配置项
	header: TableHeaderType[]; // 表头配置项
	selectedRows: EmptyObjectType[]; // 表格选中行
	tableSearch: TableSearchType[]; // 搜索表单配置项
	showSearch?: boolean; // 是否显示搜索栏
}
const props = withDefaults(defineProps<TableControlProps>(), {
	showSearch: true,
});

// 定义事件
const emit = defineEmits(["refresh", "search", "sort", "formChange"]);

// 定义变量内容
const settingIconRef = ref();
const formRef = ref<FormInstance>();
const toolSetRef = ref();
const { themeConfig } = storeToRefs(useThemeConfig());
const state = reactive({
	ruleForm: {},
	rowHeight: 0,
	isShowSearch: props.showSearch,
	checkListAll: true,
	checkListIndeterminate: false,
});

// 初始化 form 字段
if (props.tableSearch.length > 0) {
	props.tableSearch
		.filter(v => !v.isHide)
		.forEach(v => (state.ruleForm[v.prop] = cloneDeep(v.defaultValue) || ""));
}

// 查询
const onSearch = () => {
	if (!formRef.value) return;
	formRef.value.validate((valid: boolean) => {
		if (valid) {
			emit("search", cloneDeep(state.ruleForm));
		}
	});
	console.log("onSearch", state.ruleForm);
};
// 重置
const onReset = () => {
	if (!formRef.value) return;
	formRef.value.resetFields();
	emit("search", state.ruleForm, true);
};
// 展开收起搜索栏
const onShowSearch = () => {
	state.isShowSearch = !state.isShowSearch;
};
// 导出
/* const onExportTable = () => {
	if (props.selectedRows.length <= 0) return ElMessage.warning("请先选择要导出的数据");
	table2excel(
		props.header
			.filter(v => v.isCheck)
			.map(item => {
				item.type = ["text", "image"].includes(item.type) ? item.type : "text";
				return item;
			}),
		JSON.parse(JSON.stringify(props.selectedRows)),
		`${document.title} ${new Date().toLocaleString()}`
	);
}; */
// 设置 - 初始化可拖动列表
const onSetTable = () => {
	nextTick(() => {
		const sortable = Sortable.create(toolSetRef.value, {
			handle: ".handle",
			dataIdAttr: "data-key",
			animation: 150,
			onEnd: () => {
				const headerList: TableHeaderType[] = [];
				sortable.toArray().forEach(val => {
					props.header.forEach(v => {
						if (v.key === val) headerList.push({ ...v });
					});
				});
				emit("sort", headerList);
			},
		});
	});
};
// 设置 - 列显示全选改变时
const onCheckAllChange = <T>(val: T) => {
	if (val) props.header.forEach(v => (v.isCheck = true));
	else props.header.forEach(v => (v.isCheck = false));
	state.checkListIndeterminate = false;
};
// 设置 - 列显示当前项改变时
const onCheckChange = () => {
	const headers = props.header.filter(v => v.isCheck).length;
	state.checkListAll = headers === props.header.length;
	state.checkListIndeterminate = headers > 0 && headers < props.header.length;
};

// treeSelect 过滤方法
const filterTreeNode = (value: string, data: EmptyObjectType, treeProps?: EmptyObjectType) => {
	if (!value) return true;
	return data[treeProps?.label || "label"].includes(value);
};

// 监听 ruleForm 变化
watch(
	() => state.ruleForm,
	() => emit("formChange", state.ruleForm),
	{ deep: true }
);
onMounted(() => {
	// 监听 isShowSearch 变化
	watch(
		() => state.isShowSearch,
		() => {
			const tableRowElement = document.querySelector("#table-control-search-row");
			if (tableRowElement) state.rowHeight = tableRowElement.clientHeight;
		},
		{ immediate: true }
	);
});
// 暴露变量
defineExpose({
	ruleForm: state.ruleForm,
	doSearch: onSearch,
	doReset: onReset,
});
</script>

<style scoped lang="scss">
.table-control-search-container {
	flex-shrink: 0;
	display: flex;
	overflow: hidden;
	transition: height 0.25s ease-in-out;
	.table-form {
		flex: 1;
	}
}
.table-control-container {
	flex-shrink: 0;
	display: flex;
	.icon-btn {
		margin: 0;
	}
	.operation-box {
		display: flex;
	}
	.tool-box {
		flex: 1;
		display: flex;
		justify-content: flex-end;
		align-items: center;
		.tool-input-group {
			display: flex;
			align-items: center;
		}
		.tool-btn-group {
			border: 1px solid var(--el-border-color);
			border-radius: var(--el-border-radius-base);
			overflow: hidden;
			button:hover {
				color: #606266;
				background-color: var(--el-color-info-light-7);
			}
			.el-button + .el-button {
				margin: 0;
			}
			.tool-btn {
				border: none;
				border-radius: 0;
			}
			.border-right {
				border-right: 1px solid var(--el-border-color);
			}
		}
	}
}
</style>
